feat(auth): add Supabase org authz profile#2262
Draft
Sanderhoff-alt wants to merge 1 commit into
Draft
Conversation
ade3980 to
7195664
Compare
Introduce an opt-in supabase_org deployment profile that models an organization as the Hindsight tenant. The dataplane now has built-in SupabaseOrgTenantExtension and SupabaseAuthorizationExtension classes sharing a policy resolver for Supabase JWTs and Hindsight scoped API keys. The resolver maps callers to organization schemas, member roles, bank scopes, operation scopes, and tenant config without changing the existing default, API key, or user-level Supabase tenant modes. Wire profile validation into API startup, uvicorn import startup, and worker startup so partial supabase_org deployments fail fast. Expose authz profile details through version features so the control plane can detect mismatched dataplane configuration instead of silently entering a half-working state. Add the control-plane supabase_org auth provider with login, signup, logout, selected-organization cookies, organization switching, team management, manual invite links, and Hindsight scoped API key management. Existing API wrappers now create request-scoped dataplane clients, forwarding the user's Supabase JWT and X-Hindsight-Org-Id in supabase_org mode while preserving fixed dataplane API key behavior for access_key and disabled modes. Add Supabase local-stack config and migrations for organizations, memberships, invites, API keys, and bank scopes. These authorization metadata tables live in public for PostgREST access but enable RLS and define no anon/authenticated policies, so browser clients must go through the control-plane wrapper APIs while server-side code uses the service role key. Cover the implementation with resolver and extension unit tests, control-plane auth/store/header-forwarding tests, a route scan that prevents app API routes from importing global dataplane clients, and a Supabase CLI integration test that exercises real Auth, PostgREST, RLS, JWT resolution, and scoped API key resolution. The integration CI job now installs a pinned Supabase CLI and also runs when control-plane changes touch the local Supabase project. Document the implemented V1 boundaries in code and tests: manual invites only, no password recovery UI, no organization schema deletion flow, no child API keys, no memory-level ACLs, and no cross-tenant sharing.
7195664 to
414446b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2235.
This is a first implementation slice and does not close the full issue.
Summary
This PR adds an opt-in Supabase-backed organization authorization profile for OSS deployments that want a Hindsight Cloud-like team model without changing the existing default, fixed API key, or per-user Supabase tenant modes.
The new
supabase_orgprofile models an organization as the Hindsight tenant. A user can belong to multiple organizations, and the selected organization maps to the tenant schema used by the dataplane. The implementation adds built-in dataplane extensions, Supabase-backed policy resolution with request-context policy reuse, control-plane auth/session plumbing, organization switching and rename, team management, manual invite links, and Hindsight scoped API key management.What Changed
Dataplane
SupabaseOrgTenantExtensionfor resolving either a Supabase JWT plusX-Hindsight-Org-Id, or a Hindsight scoped API key, to an organization tenant schema.SupabaseAuthorizationExtensionfor enforcing organization roles, operation scopes, and bank-scoped API keys through the existingOperationValidatorExtensioninterface.SupabasePolicyResolverfor credential parsing, Supabase lookups, and caller policy construction. The tenant extension stores the resolvedCallerPolicyonRequestContext, and the authorization extension reuses it before falling back to another resolve.HINDSIGHT_API_AUTHZ_PROFILE=supabase_orgprofile validation so partial deployments fail fast instead of running with only tenant resolution or only operation authorization enabled.supabase_org_readyso the control plane can detect mismatched deployments.Control Plane
HINDSIGHT_CP_AUTH_PROVIDER=supabase_orgalongside the existing disabled and access-key modes./api/me.PATCH /api/organizations/:id.HINDSIGHT_CP_DATAPLANE_API_KEYbehavior for existing access-key and disabled deployments.Supabase Metadata
organizations,organization_members,organization_invites,hindsight_api_keys, andhindsight_api_key_bank_scopes.Tests and CI
Current V1 Boundaries
This PR intentionally keeps the first version at organization, role, Bank, and API key scope. It does not add memory-level ACLs, row-level memory authorization, cross-tenant sharing, billing or usage metering, or enterprise IAM/SSO.
The current V1 behavior is:
DELETE /api/organizations/:idroute or deletion UI because deleting an organization requires coordinated Hindsight tenant schema cleanup./api/api-keys/scopedimplementation.HINDSIGHT_AUTH_ORG_CREATION_POLICY=direct_signup_onlyallows default organization creation during direct signup but rejects post-login organization creation throughPOST /api/organizations.Compatibility
The feature is fully opt-in. Existing deployments continue to use the same behavior unless they explicitly configure the new profile.
Existing modes remain separate:
ApiKeyTenantExtension: fixed API key, single schema behavior.SupabaseTenantExtension: existing Supabase user-to-schema behavior.supabase_org: new organization/team authorization profile requiring bothSupabaseOrgTenantExtensionandSupabaseAuthorizationExtension.A complete supabase_org deployment configures both dataplane and control plane pieces, for example:
Validation
Validated locally with:
Pre-commit lint passed during commit creation. The unused-code advisory reported an environment issue while resolving
typescriptfrom the npx cache, but it did not block the commit.